home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / ISERVER.ZIP / MFCISAPI.ZIP / ISERVER.CPP < prev    next >
C/C++ Source or Header  |  1997-01-09  |  9KB  |  314 lines

  1. // IServer.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "cbisapi.h"
  6. #include "IServer.h"
  7. #include <malloc.h>
  8. #include <afxconv.h>  // BSTR conversions
  9.  
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15.  
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CIsapiServer
  18.  
  19. IMPLEMENT_DYNCREATE(CIsapiServer, CCmdTarget)
  20.  
  21. CIsapiServer::CIsapiServer()
  22. {
  23.     EnableAutomation();
  24. }
  25.  
  26. CIsapiServer::~CIsapiServer()
  27. {
  28. }
  29.  
  30.  
  31. void CIsapiServer::OnFinalRelease()
  32. {
  33.     CCmdTarget::OnFinalRelease();
  34. }
  35.  
  36.  
  37. BEGIN_MESSAGE_MAP(CIsapiServer, CCmdTarget)
  38.     //{{AFX_MSG_MAP(CIsapiServer)
  39.     // NOTE - the ClassWizard will add and remove mapping macros here.
  40.     //}}AFX_MSG_MAP
  41. END_MESSAGE_MAP()
  42.  
  43. BEGIN_DISPATCH_MAP(CIsapiServer, CCmdTarget)
  44.     //{{AFX_DISPATCH_MAP(CIsapiServer)
  45.     DISP_PROPERTY(CIsapiServer, "RetVal", m_retVal, VT_I4)
  46.     DISP_PROPERTY(CIsapiServer, "StatCode", m_statCode, VT_I4)
  47.     DISP_PROPERTY_EX(CIsapiServer, "Method", GetMethod, SetNotSupported, VT_BSTR)
  48.     DISP_PROPERTY_EX(CIsapiServer, "QueryString", GetQueryString, SetNotSupported, VT_BSTR)
  49.     DISP_PROPERTY_EX(CIsapiServer, "PathInfo", GetPathInfo, SetNotSupported, VT_BSTR)
  50.     DISP_PROPERTY_EX(CIsapiServer, "PathTranslated", GetPathTranslated, SetNotSupported, VT_BSTR)
  51.     DISP_PROPERTY_EX(CIsapiServer, "ContentLength", GetContentLength, SetNotSupported, VT_I4)
  52.     DISP_PROPERTY_EX(CIsapiServer, "Content", GetContent, SetNotSupported, VT_BSTR)
  53.     DISP_PROPERTY_EX(CIsapiServer, "ContentType", GetContentType, SetNotSupported, VT_BSTR)
  54.     DISP_FUNCTION(CIsapiServer, "Write", Write, VT_BOOL, VTS_VARIANT)
  55.     DISP_FUNCTION(CIsapiServer, "ServerVariable", ServerVariable, VT_BOOL, VTS_VARIANT VTS_PVARIANT)
  56.     DISP_FUNCTION(CIsapiServer, "WriteLine", WriteLine, VT_BOOL, VTS_VARIANT)
  57.     DISP_FUNCTION(CIsapiServer, "WriteByte", WriteByte, VT_BOOL, VTS_VARIANT)
  58.     DISP_FUNCTION(CIsapiServer, "ServerDoneSession", ServerDoneSession, VT_BOOL, VTS_NONE)
  59.     DISP_FUNCTION(CIsapiServer, "Redirect", Redirect, VT_BOOL, VTS_VARIANT)
  60.     DISP_FUNCTION(CIsapiServer, "SendURL", SendURL, VT_BOOL, VTS_VARIANT)
  61.     DISP_FUNCTION(CIsapiServer, "SendHeaders", SendHeaders, VT_BOOL, VTS_VARIANT VTS_VARIANT)
  62.     DISP_FUNCTION(CIsapiServer, "MapURL2Path", MapURL2Path, VT_BOOL, VTS_PVARIANT)
  63.     //}}AFX_DISPATCH_MAP
  64. END_DISPATCH_MAP()
  65.  
  66. // Note: we add support for IID_IIsapiServer to support typesafe binding
  67. //  from VBA.  This IID must match the GUID that is attached to the 
  68. //  dispinterface in the .ODL file.
  69. // Not really used in any meaningful way, but the wiz puts it here
  70.  
  71. // {A3B7D305-647C-11D0-A7B2-444553540000}
  72. static const IID IID_IIsapiServer =
  73. { 0xa3b7d305, 0x647c, 0x11d0, { 0xa7, 0xb2, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0 } };
  74.  
  75. BEGIN_INTERFACE_MAP(CIsapiServer, CCmdTarget)
  76.     INTERFACE_PART(CIsapiServer, IID_IIsapiServer, Dispatch)
  77. END_INTERFACE_MAP()
  78.  
  79. /////////////////////////////////////////////////////////////////////////////
  80. // CIsapiServer message handlers
  81.  
  82. // Write to client
  83. BOOL CIsapiServer::Write(const VARIANT FAR& idata) 
  84. {
  85.     COleVariant data=idata;
  86.     USES_CONVERSION;
  87.     data.ChangeType(VT_BSTR);  // Force to BSTR
  88.     if (data.vt!=VT_BSTR)
  89.         return FALSE;
  90.     char *s=W2A(data.bstrVal);  // switch to ANSI
  91.     DWORD siz=strlen(s);
  92.     return ecb->WriteClient(ecb->ConnID,s,&siz,0); // out!
  93. }
  94.  
  95. // This fetches a Server Variable into a VARIANT
  96. // Be careful. Since the second argument is a variant
  97. // by reference, the formal argument must really be
  98. // a variant. In other words, NO:
  99. //    dim x as string
  100. //    server.ServerVariable "SCRIPT_NAME",x
  101. // YES:
  102. //      dim x as variant
  103. //    server.ServerVariable "SCRIPT_NAME",x
  104. // Probably should have been a function returning VARIANT, but then
  105. // again...
  106. BOOL CIsapiServer::ServerVariable(const VARIANT FAR& Variable, 
  107.                                   VARIANT FAR* Result) 
  108. {
  109.     COleVariant var;
  110.     var=Variable;
  111.     var.ChangeType(VT_BSTR);
  112.     if (var.vt!=VT_BSTR) return FALSE;
  113.  
  114.     USES_CONVERSION;
  115.     char *v=W2A(var.bstrVal);
  116.     CString res;
  117.     DWORD siz=1024;
  118.     BOOL rv;
  119.     rv=ecb->GetServerVariable(ecb->ConnID,v,
  120.         (char *)res.GetBufferSetLength(siz),&siz);
  121.     res.ReleaseBuffer(siz-1);
  122.     VariantClear(Result);
  123.     Result->vt=VT_BSTR;
  124.     Result->bstrVal=res.AllocSysString();
  125.     return rv;
  126. }
  127.  
  128. // R/O Property -- these all look the same
  129. BSTR CIsapiServer::GetMethod() 
  130. {
  131.     CString strResult=ecb->lpszMethod;
  132.     BSTR rv;
  133.     rv=strResult.AllocSysString();
  134.     return rv;
  135. }
  136.  
  137. // Another R/O Property
  138. BSTR CIsapiServer::GetQueryString() 
  139. {
  140.     CString strResult=ecb->lpszQueryString;
  141.     BSTR rv;
  142.     rv=strResult.AllocSysString();
  143.     return rv;
  144. }
  145.  
  146. // R/O Property
  147. BSTR CIsapiServer::GetPathInfo() 
  148. {
  149.     CString strResult=ecb->lpszPathInfo;
  150.     BSTR rv;
  151.     rv=strResult.AllocSysString();
  152.     return rv;
  153. }
  154.  
  155. // R/O Property
  156. BSTR CIsapiServer::GetPathTranslated() 
  157. {
  158.     CString strResult=ecb->lpszPathTranslated;
  159.     BSTR rv;
  160.     rv=strResult.AllocSysString();
  161.     return rv;
  162. }
  163.  
  164. // R/O Property
  165. long CIsapiServer::GetContentLength() 
  166. {
  167.     return ecb->cbTotalBytes;
  168. }
  169.  
  170. // R/O Property with a twist
  171. // Apparently sometimes the server calls the
  172. // extension without having all the content
  173. // data (does this really happen?)
  174. // This function reads it all so it is available
  175. // BTW, the docs say that if the count is
  176. // 0xFFFFFFFF then MORE than 4G of data
  177. // is forthcoming and you should call ReadClient
  178. // until it is empty
  179. // NEWS BULLETIN: If you expect 4G or more in
  180. // a request, don't use these functions!
  181. BSTR CIsapiServer::GetContent() 
  182. {
  183.     CString strResult;
  184.     char *p=strResult.GetBufferSetLength(ecb->cbTotalBytes);
  185.     // put available bytes in CString
  186.     memcpy(p,ecb->lpbData,ecb->cbAvailable);
  187.     // Read excess
  188.     if (ecb->cbAvailable!=ecb->cbTotalBytes)
  189.         {
  190.         DWORD siz=ecb->cbTotalBytes-ecb->cbAvailable;
  191.         ecb->ReadClient(ecb->ConnID,p+ecb->cbAvailable,&siz);
  192.         }
  193.     strResult.ReleaseBuffer(ecb->cbTotalBytes);
  194.     BSTR rv;
  195.     rv=strResult.AllocSysString();
  196.     return rv;
  197. }
  198.  
  199. // Another R/O
  200. BSTR CIsapiServer::GetContentType() 
  201. {
  202.     CString strResult=ecb->lpszContentType;
  203.     BSTR rv;
  204.     rv=strResult.AllocSysString();
  205.     return rv;
  206. }
  207.  
  208. // Simple Method to write a line
  209. // Note that HTML doesn't care one
  210. // whit about the \r\n -- it just
  211. // makes the HTML source nicer
  212. // Use <P> or <BR> to get a newline in HTML
  213. BOOL CIsapiServer::WriteLine(const VARIANT FAR& idata) 
  214. {
  215.     BOOL rv=Write(idata);
  216.     DWORD siz=2;
  217.     if (rv) rv=ecb->WriteClient(ecb->ConnID,"\r\n",&siz,0);
  218.     return rv;
  219. }
  220.  
  221. // Write a byte out
  222. BOOL CIsapiServer::WriteByte(const VARIANT FAR& byte) 
  223. {
  224.     COleVariant num=byte;
  225.     num.ChangeType(VT_UI1);
  226.     if (num.vt!=VT_UI1)
  227.         return FALSE;
  228.     char s=num.bVal;
  229.     DWORD siz=1;
  230.     return ecb->WriteClient(ecb->ConnID,&s,&siz,0);
  231. }
  232.  
  233.  
  234. // Wrap ServerSupportFunction Done with Session
  235. BOOL CIsapiServer::ServerDoneSession() 
  236. {
  237.     return ecb->ServerSupportFunction(ecb->ConnID,
  238.         HSE_REQ_DONE_WITH_SESSION,NULL,NULL,NULL);
  239. }
  240.  
  241. // Redirect to another URL (wrap ServerSupportFunction)
  242. BOOL CIsapiServer::Redirect(const VARIANT FAR& url) 
  243. {
  244.     COleVariant var;
  245.     var=url;
  246.     var.ChangeType(VT_BSTR);
  247.     if (var.vt!=VT_BSTR) return FALSE;
  248.  
  249.     USES_CONVERSION;
  250.     char *v=W2A(var.bstrVal);
  251.     DWORD siz=strlen(v);
  252.     return ecb->ServerSupportFunction(ecb->ConnID,
  253.         HSE_REQ_SEND_URL_REDIRECT_RESP,v,&siz,NULL);
  254. }
  255.  
  256.  
  257. // Send alternate URL (wrap ServerSupportFunction)
  258. BOOL CIsapiServer::SendURL(const VARIANT FAR& url) 
  259. {
  260.     COleVariant var;
  261.     var=url;
  262.     var.ChangeType(VT_BSTR);
  263.     if (var.vt!=VT_BSTR) return FALSE;
  264.  
  265.     USES_CONVERSION;
  266.     char *v=W2A(var.bstrVal);
  267.     DWORD siz=strlen(v);
  268.     return ecb->ServerSupportFunction(ecb->ConnID,
  269.         HSE_REQ_SEND_URL,v,&siz,NULL);
  270. }
  271.  
  272.  
  273. // Send headers (wrap ServerSupport Function)
  274. BOOL CIsapiServer::SendHeaders(const VARIANT FAR& Status, 
  275.                                const VARIANT FAR& Headers) 
  276. {
  277.     COleVariant var,var2;
  278.     var=Status;
  279.     var2=Headers;
  280.     var.ChangeType(VT_BSTR);
  281.     if (var.vt!=VT_BSTR) return FALSE;
  282.     var2.ChangeType(VT_BSTR);
  283.     if (var.vt!=VT_BSTR) return FALSE;
  284.  
  285.     USES_CONVERSION;
  286.     char *status=W2A(var.bstrVal);
  287.     char *hdr=W2A(var.bstrVal);
  288.     return ecb->ServerSupportFunction(ecb->ConnID,
  289.         HSE_REQ_SEND_RESPONSE_HEADER,status,NULL,(DWORD *)hdr);
  290. }
  291.  
  292. // Map Virtual Path to Real Path (wrap ServerSupportFunction)
  293. BOOL CIsapiServer::MapURL2Path(VARIANT FAR* urlpath) 
  294. {
  295.     BOOL rv;
  296.     COleVariant var,var2;
  297.     var=urlpath;
  298.     var.ChangeType(VT_BSTR);
  299.     if (var.vt!=VT_BSTR) return FALSE;
  300.     USES_CONVERSION;
  301.     char *varin=W2A(var.bstrVal);
  302.     DWORD siz=1024;
  303.     CString url(varin);
  304.     rv=ecb->ServerSupportFunction(ecb->ConnID,
  305.         HSE_REQ_MAP_URL_TO_PATH,
  306.         url.GetBufferSetLength(siz),&siz,NULL);
  307.     url.ReleaseBuffer(siz-1);
  308.     // set up return value
  309.     VariantClear(urlpath);
  310.     urlpath->vt=VT_BSTR;
  311.     urlpath->bstrVal=url.AllocSysString();
  312.     return rv;
  313. }
  314.